package com.hioove.core.process;

import com.hioove.core.annotation.*;
import com.hioove.core.aop.annotation.*;
import com.hioove.core.aop.model.MethodEnhance;
import com.hioove.core.filter.FilterChain;
import com.hioove.core.filter.annotation.Filter;
import com.hioove.core.ioc.model.AttributeInjection;
import com.hioove.core.model.base.config.*;
import com.hioove.core.reflect.Proxy;
import com.hioove.core.util.Builder;
import com.hioove.core.util.ClassUtils;
import com.hioove.core.util.Commons;
import com.hioove.core.util.FileUtils;
import com.hioove.core.web.mvc.model.RouteSupport;
import com.hioove.core.web.mvc.model.SqlInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * hioove 核心实现
 */
public class Load {
    final static Logger log = LoggerFactory.getLogger(Load.class);


    // 1. 加载启动类 分析启动类注解
    public static StartClassInfo startClass(Class<?> app, String[] args) {
        // 1.加载主程序入口的注解
        Annotation[] appAnnotations = app.getAnnotations();
        // 判断是否具备启动的必要条件
        assert Arrays.stream(app.getAnnotations()).map(Annotation::annotationType).collect(Collectors.toList()).stream().anyMatch(clazz -> clazz.equals(SpringBootApplication.class));
        return Builder.of(StartClassInfo::new)
                .with(StartClassInfo::setAnnotations, Arrays.asList(app.getAnnotations()))
                .with(StartClassInfo::setStartClass, app)
                .build();
    }

    // 2. 加载配置信息
    public static ConfigInfor configInfo(StartClassInfo startClassConfig, String... args) {
        // 系统信息加载
        Properties systemEnv = System.getProperties();
        Properties defaultInfo = new Properties();
        try {
            defaultInfo.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(Commons.DEFAULT_INFO));
        } catch (IOException e) {
            log.error("", e);
        }
        Yaml yaml = new Yaml();
        InputStream resourceAsStream = Load.class.getClassLoader().getResourceAsStream(String.valueOf(defaultInfo.get("sql.path")));
        LinkedHashMap sqlSupport = Objects.isNull(resourceAsStream) ? null : yaml.load(resourceAsStream);
        return Builder.of(ConfigInfor::new)
                .with(ConfigInfor::setSystemEnv, new HashMap<>(systemEnv))
                .with(ConfigInfor::setDefaultInfo, new HashMap<>(defaultInfo))
                .with(ConfigInfor::setSqlInfo, sqlSupport)
                .build();
    }

    // 3. 扫描待实例化的对象 将要实例化
    public static Map<String, ClassSupport> scanObjectsToBeInstantiated(StartClassInfo startClassInfo, ConfigInfor configInfor) {
        // 1.加载依赖了时是否具备条件 是否包含注解 EnableAutoConfiguration
        assert startClassInfo.getAnnotations().stream().map(Annotation::annotationType).collect(Collectors.toList()).stream().anyMatch(clazz -> clazz.equals(EnableAutoConfiguration.class));
        // 2.扫描待实例化的对象
        String appPath = startClassInfo.getStartClass().getResource(Commons.NULL_CHARACTER).getFile();
        File appfile = new File(appPath);
        String absolutePath = appfile.getAbsolutePath().replace(File.separator, Commons.DOT);
        String name = Commons.DOT + startClassInfo.getStartClass().getPackage().getName();
        String uselessPrefix = absolutePath.substring(0, absolutePath.length() - name.length() + 1);
        ArrayList<File> fileCache = Builder.of(ArrayList<File>::new).build();
        Arrays.stream(Objects.requireNonNull(appfile.listFiles())).forEach(f -> FileUtils.findClassFiles(f, fileCache, new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return true;
            }
        }));
        List<String> collect = startClassInfo.getAnnotations().stream().filter(annotation -> annotation instanceof SpringBootApplication).map(annotation -> {
            return Arrays.asList(((SpringBootApplication) annotation).scanBasePackages());
        }).flatMap(Collection::stream).collect(Collectors.toList());
        // 3.过滤掉包含$的类名
        return fileCache.stream().filter(file -> !file.getAbsolutePath().contains(Commons.MONEY)).map(file -> {
            String classOriginalPath = file.getAbsolutePath().substring(uselessPrefix.length());
            return Builder.of(ClassSupport::new)
                    .with(ClassSupport::setName, classOriginalPath.replace(File.separator, Commons.DOT).replace(Commons.CLASS_SUFFIX, Commons.NULL_CHARACTER))
                    .with(ClassSupport::setFile, file)
                    .build();
        })/*.filter(classSupport -> {
            return collect.stream()
                    .anyMatch(packageName -> {
                        return packageName.length() <= classSupport.getName().length() && packageName.equals(classSupport.getName().substring(0, packageName.length()));
                    });
        })*/.collect(Collectors.toMap(ClassSupport::getName, Function.identity()));
    }

    // 4. 加载配置类(主要  涉及带有配置类注解的类实例化 。eg. Component.class Bean.class (只涉及Bean的实例化)
    public static ConfigInstance configObj(StartClassInfo startClassInfo,
                                           ConfigInfor configInfor, Map<String, ClassSupport> tobeInstance) {
        // 所有的被扫描类进行分析 并生成 MethodSupport.class
        Map<String, ClassSupport> configurationClass = tobeInstance.keySet().stream().map(classReference -> {
            // 1.加载待实例化的类进行分析  a.注解
            Class<?> currentClass = ClassUtils.load(classReference);
            ClassSupport classSupport = tobeInstance.get(classReference);
            // 2.获取类上的方法和注解
            Map<String, MethodSupport> methodAnnotation = Arrays.stream(Objects.requireNonNull(currentClass).getDeclaredMethods()).map(method -> {
                return Builder.of(MethodSupport::new)
                        .with(MethodSupport::setName, method.getName())
                        .with(MethodSupport::setAnnotations, Arrays.asList(method.getAnnotations()))
                        .with(MethodSupport::setParamTypes, Arrays.asList(method.getParameterTypes()))
                        .with(MethodSupport::setMethod, method)
                        .with(MethodSupport::setClassSupport, classSupport)
                        .build();
            }).collect(Collectors.toMap(methodSupport -> methodSupport.getName() + UUID.randomUUID(), Function.identity()));
            // 2.获取类上的属性和注解
            Map<String, FieldSupport> fieldAnnotation = Arrays.stream(Objects.requireNonNull(currentClass).getDeclaredFields()).map(field -> {
                return Builder.of(FieldSupport::new)
                        .with(FieldSupport::setName, field.getName())
                        .with(FieldSupport::setAnnotations, Arrays.asList(field.getAnnotations()))
                        .with(FieldSupport::setFieldType, field.getType())
                        .with(FieldSupport::setField, field)
                        .with(FieldSupport::setClassSupport, classSupport)
                        .build();
            }).collect(Collectors.toMap(fieldSupport -> fieldSupport.getName() + UUID.randomUUID(), Function.identity()));
            // 当前类
            Builder.of(classSupport)
                    .with(ClassSupport::setClazz, currentClass)
                    .with(ClassSupport::setAnnotations, Arrays.asList(Objects.requireNonNull(currentClass).getAnnotations()))
                    .with(ClassSupport::setMethodSupport, methodAnnotation)
                    .with(ClassSupport::setFieldSupport, fieldAnnotation)
                    .with(ClassSupport::setSuperClazz, ClassUtils.allSuperclass(currentClass))
                    .with(ClassSupport::setInterfaces, Arrays.asList(currentClass.getInterfaces()))
                    .build();
            return classSupport;
            // 3.过滤出类上包含Component 注解的类
        }).filter(classSupport -> {
            return classSupport.getAnnotations().stream()
                    .anyMatch(annotation -> {
                        return annotation instanceof Component || annotation instanceof Configuration;
                    });
        }).collect(Collectors.toMap(ClassSupport::getName, Function.identity()));
        // 填充子类类型
        tobeInstance.values().forEach(classSupport -> {
            ArrayList<Class<?>> subclass = tobeInstance.values().stream().filter(clazzConfig -> {
                return clazzConfig.getInterfaces().stream().anyMatch(interFace -> {
                    return interFace.equals(classSupport.getClazz());
                });
            }).map(ClassSupport::getClazz).collect(Collectors.toCollection(ArrayList<Class<?>>::new));
            classSupport.setSubClazz(subclass);
        });


        //todo 4.开始实例化配置类
        Map<String, Object> beanCalss = configurationClass.values().stream().map(classSupport -> {
            // 5.查找存在Bean注解的
            Object componentInstance = null;
            try {
                componentInstance = classSupport.getClazz().newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            Object copyComponentInstance = componentInstance;
            // 直接保存
            // 6.实例化方法上定义的Bean注解
            return classSupport.getMethodSupport().values().stream().map(methodSupport -> {
                // 7.对方法体的每个注解检索查看是否存在Bean
                // 只是针对带有Bean 注解开始实例话
                // 获取到当前的方法
                return methodSupport.getAnnotations().stream().filter(annotation -> annotation instanceof Bean).map(annotation -> {
                    Object configInstance = null;
                    Map<String, Object> collect1 = null;
                    Method method = methodSupport.getMethod();
                    try {
                        configInstance = method.invoke(copyComponentInstance, new Object[]{});
                        // 如果未定义Bean.value 则这个类的检索名称时方法名称MethodName
                        // 如果Bean上面定义多个 value e.g @Bean(value={“v1,v2”}) 则会创建多个在缓存中创建多个key 指向同一个类
                        Object copyConfigInstance = configInstance;
                        collect1 = Arrays.stream(Optional.of(((Bean) annotation).value()).filter(strings -> strings.length != 0).orElse(new String[]{methodSupport.getName()}))
                                .collect(HashMap<String, Object>::new, (hashMap, s) -> hashMap.put(s, copyConfigInstance), HashMap::putAll);
                    } catch (Exception e) {
                        log.debug("{} {} Cannot be instantiated！！！", classSupport.getClazz(), method.getName());
                    }
                    return collect1;
                }).collect(HashMap<String, Object>::new, HashMap::putAll, HashMap::putAll);
            }).collect(HashMap<String, Object>::new, HashMap::putAll, HashMap::putAll);
        }).collect(HashMap<String, Object>::new, HashMap::putAll, HashMap::putAll);

        //todo 针对aop 处理
        Builder<MethodEnhance> methodEnhanceBuilder = Builder.of(MethodEnhance::new);
        //
        List<MethodSupport> collect = tobeInstance.values().stream().filter(classSupport -> {
            return classSupport.getAnnotations().stream().anyMatch(annotation -> {
                return annotation instanceof Aspect;
            });
        }).map(classSupport -> {
            Object aspectInstanc = null;
            // 实例化 拦截配置类
            try {
                aspectInstanc = Objects.requireNonNull(ClassUtils.create(classSupport.getName())).newInstance();
            } catch (Exception e) {
                log.debug("Error creating aop object!!!");
            }
            Object copyAspectInstanc = aspectInstanc;
            return classSupport.getMethodSupport().values().stream().filter(methodSupport -> {
                return methodSupport.getAnnotations().stream().anyMatch(annotation -> {
                    // 只考虑 包含 After.class Before.class 注解的方法体
                    return annotation instanceof After || annotation instanceof Before || annotation instanceof Pointcut
                            || annotation instanceof AfterReturning || annotation instanceof AfterThrowing || annotation instanceof Around;
                });
            }).map(methodSupport -> {
                return
                        Builder.of(methodSupport).with(MethodSupport::setInstance, copyAspectInstanc).build();
            }).peek(methodSupport -> {
                methodSupport.getAnnotations().stream().filter(annotation -> annotation instanceof Pointcut).forEach(annotation -> {
                    methodEnhanceBuilder.with(MethodEnhance::addPointcut, methodSupport);
                });
                methodSupport.getAnnotations().stream().filter(annotation -> annotation instanceof After).forEach(annotation -> {
                    methodEnhanceBuilder.with(MethodEnhance::addAfter, methodSupport);
                });
                methodSupport.getAnnotations().stream().filter(annotation -> annotation instanceof Before).forEach(annotation -> {
                    methodEnhanceBuilder.with(MethodEnhance::addBefore, methodSupport);
                });
                methodSupport.getAnnotations().stream().filter(annotation -> annotation instanceof AfterReturning).forEach(annotation -> {
                    methodEnhanceBuilder.with(MethodEnhance::addAfterReturning, methodSupport);
                });
                methodSupport.getAnnotations().stream().filter(annotation -> annotation instanceof AfterThrowing).forEach(annotation -> {
                    methodEnhanceBuilder.with(MethodEnhance::addAfterThrowing, methodSupport);
                });
                methodSupport.getAnnotations().stream().filter(annotation -> annotation instanceof Around).forEach(annotation -> {
                    methodEnhanceBuilder.with(MethodEnhance::addAround, methodSupport);
                });
            }).collect(Collectors.toCollection(ArrayList<MethodSupport>::new));
        }).flatMap(Collection::stream).collect(Collectors.toList());
        //todo 针对Filter 处理
        Builder<FilterChain> filterchain = Builder.of(FilterChain::new);
        List<MethodSupport> copyMethodFilterBuilder = tobeInstance.values().stream().filter(classSupport -> {
            return classSupport.getAnnotations().stream().anyMatch(annotation -> annotation instanceof Filter);
        }).map(classSupport -> {
            Object aspectInstanc = null;
            // 实例化 拦截配置类
            try {
                aspectInstanc = Objects.requireNonNull(ClassUtils.create(classSupport.getName())).newInstance();
            } catch (Exception e) {
                log.debug("Error creating Filter object!!!");
            }
            Object copyAspectInstanc = aspectInstanc;
            return classSupport.getMethodSupport().values().stream().map(methodSupport -> {
                filterchain.with(FilterChain::addFilters, methodSupport);
                return Builder.of(methodSupport).with(MethodSupport::setInstance, copyAspectInstanc).build();
            }).collect(Collectors.toCollection(ArrayList<MethodSupport>::new));
        }).flatMap(Collection::stream).collect(Collectors.toList());
        return Builder.of(ConfigInstance::new)
                .with(ConfigInstance::addAnnotationInstance, Aspect.class, methodEnhanceBuilder.build())
                .with(ConfigInstance::addAnnotationInstance, Filter.class, filterchain.build())
                .with(ConfigInstance::addAnnotationInstance, Bean.class, beanCalss).build();
    }

    // 5. 初步实例化类对象 完成类增强 eg. RestController.class  Service.class  Repository.class (只涉及Bean的实例化 包括增强类)
    public static Map<Class<?>, Object> mvcObj(StartClassInfo startClassInfo, ConfigInfor configInfor, Map<String, ClassSupport> tobeInstance, ConfigInstance configInstance) {
        // 取出所有的路由信息
        tobeInstance.values().stream().filter(classSupport -> {
            return classSupport.getAnnotations().stream().anyMatch(annotation -> {
                return annotation instanceof RestController;
            });
        }).map(classSupport -> {
            ArrayList<RouteSupport> routeInfors = classSupport.getMethodSupport().values().stream().filter(methodSupport -> methodSupport.getAnnotations().stream().anyMatch(annotation -> annotation instanceof RequestMapping))
                    .map(methodSupport -> {
                        return Builder.of(RouteSupport::new).with(RouteSupport::addRoute, ((RequestMapping) methodSupport.getMethod().getAnnotation(RequestMapping.class)).value(), methodSupport).build();
                    }).collect(Collectors.toCollection(ArrayList<RouteSupport>::new));
            classSupport.setRoutInfors(routeInfors);
            return routeInfors;
        }).flatMap(Collection::stream).collect(Collectors.toList());

        // 找出框架管理的类进行实例化
        return tobeInstance.values().stream().filter(classSupport -> {
            return classSupport.getAnnotations().stream().anyMatch(annotation -> {
                        return annotation instanceof RestController || annotation instanceof Service || annotation instanceof Repository;
                    }
            );
        }).filter(classSupport -> !classSupport.getClazz().isInterface()).map(classSupport -> {
            MethodEnhance annotationInstanceObj = (MethodEnhance) configInstance.getAnnotationInstance().get(Aspect.class);
            // 面向接口编程 可以选择实现逻辑
            Proxy proxy = Builder.of(Proxy.INSTANCE)
                    .with(Proxy::setBefore, annotationInstanceObj.getBefore())
                    .with(Proxy::setAfter, annotationInstanceObj.getAfter())
                    .with(Proxy::setPointcut, annotationInstanceObj.getPointcut())
                    .build();
            Object proxyObj = proxy.create(classSupport.getClazz());
            return Builder.of(HashMap<Class<?>, Object>::new).with(HashMap::put, classSupport.getClazz(), proxyObj).build();
        }).collect(HashMap<Class<?>, Object>::new, HashMap::putAll, HashMap::putAll);
    }

    // 6. 注入实例见对象 完成最终实例化
    public static AttributeInjection resolveInterdependence(StartClassInfo startClassInfo, ConfigInfor
            configInfo, Map<String, ClassSupport> tobeObj, ConfigInstance configObj, Map<Class<?>, Object> mvcObj) {
        // 到这里已经实例化的有   configurationObj 里面含 Bean.class  Aspect.class 注解 都初步实例化
        // 到这里已经实例化的有   instantiateClassObject 里面含 RestController.class  Service.class  Repository.class 注解 都初步实例化
        // 先获取所有的带有Autowired.class Resource.class类属性
        Collection<Object> values = configObj.getAnnotationInstance().values();
        Builder<AttributeInjection> attributeInjectionBuilder = Builder.of(AttributeInjection::new);
        List<FieldSupport> collect = tobeObj.values().stream().map(classSupport -> {
            return classSupport.getFieldSupport().values().stream().filter(fieldSupport -> {
                return fieldSupport.getAnnotations().stream().anyMatch(annotation -> {
                    return annotation instanceof Autowired || annotation instanceof Resource;
                });
            }).map(fieldSupport -> {
                // 需要考虑 configurationObj instantiateClassObject 未完成注入的情况
                Object currentObj = mvcObj.get(classSupport.getClazz());
                return
                        Builder.of(fieldSupport).with(FieldSupport::setInstance, currentObj).build();
            }).peek(fieldSupport -> {
                fieldSupport.getAnnotations().stream().filter(annotation -> annotation instanceof Autowired).forEach(annotation -> {
                    attributeInjectionBuilder.with(AttributeInjection::addToBeInjected, Autowired.class, fieldSupport);
                });
                fieldSupport.getAnnotations().stream().filter(annotation -> annotation instanceof Resource).forEach(annotation -> {
                    attributeInjectionBuilder.with(AttributeInjection::addToBeInjected, Resource.class, fieldSupport);
                });
                fieldSupport.getAnnotations().stream().filter(annotation -> annotation instanceof Value).forEach(annotation -> {
                    attributeInjectionBuilder.with(AttributeInjection::addToBeInjected, Value.class, fieldSupport);
                });
            }).collect(Collectors.toCollection(ArrayList<FieldSupport>::new));
        }).flatMap(Collection::stream).collect(Collectors.toList());
        AttributeInjection attributeInjection = attributeInjectionBuilder.build();
        // 存储注入的对象
        HashMap<Class<?>, Object> newInjectedObject = Builder.of(HashMap<Class<?>, Object>::new).build();
        // 保存初次实例化对象
        HashMap<Class<?>, Object> initInstance = Builder.of(HashMap<Class<?>, Object>::new).build();
        // 保存初次实例化对象拷贝 针对非接口型参数注入
        HashMap<Object, Object> copyInitInstance = Optional.ofNullable(attributeInjection).orElseGet(
                AttributeInjection::new).getToBeInjected().values().stream().map(fieldSupports -> {
            return fieldSupports.stream().filter(fieldSupport -> !fieldSupport.getFieldType().isInterface()).collect(Collectors.toList());
        }).map(fieldSupports -> {
            return fieldSupports.stream().map(fieldSupport -> {
                // 开启对私有变量进行注入
                fieldSupport.getField().setAccessible(true);
                ClassSupport classSupport = fieldSupport.getClassSupport();
                Class<?> currentClass = classSupport.getClazz();

                //TODO 针对属性带有 Autowired.class 注解处理
                fieldSupport.getAnnotations().stream().filter(annotation -> {
                    return annotation instanceof Autowired;
                }).forEach(annotation -> {// 这里没有拆解是为了方便理解
                    // 针对属性进行注入
                    Object currentObj = fieldSupport.getInstance();
                    try {
                        fieldSupport.getField().set(currentObj, Analysis.getClassByType(fieldSupport.getFieldType(), tobeObj, configObj, mvcObj, newInjectedObject));
                    } catch (IllegalAccessException e) {
                        log.error("", e);
                    }
                    fieldSupport.setInstance(currentObj);
                    Builder.of(initInstance).with(HashMap::put, currentClass, currentObj).build();
                });
                //TODO 针对属性带有 Resource.class 注解处理
                fieldSupport.getAnnotations().stream().filter(annotation -> {
                    return annotation instanceof Resource;
                }).forEach(annotation -> {
                    // 针对属性进行注入
                    Object currentObj = fieldSupport.getInstance();
                    try {
                        fieldSupport.getField().set(currentObj, Analysis.getClassByType(fieldSupport.getFieldType(), tobeObj, configObj, mvcObj, newInjectedObject));
                    } catch (IllegalAccessException e) {
                        log.error("", e);
                    }
                    fieldSupport.setInstance(currentObj);
                    Builder.of(initInstance).with(HashMap::put, currentClass, currentObj).build();
                });
                //TODO 针对属性带有 Resource.class 注解处理
                fieldSupport.getAnnotations().stream().filter(annotation -> {
                    return annotation instanceof Value;
                }).forEach(annotation -> {
                    // 针对属性进行注入
                    Object currentObj = fieldSupport.getInstance();
                    try {
                        fieldSupport.getField().set(currentObj, Analysis.getClassByType(fieldSupport.getFieldType(), tobeObj, configObj, mvcObj, newInjectedObject));
                    } catch (IllegalAccessException e) {
                        log.error("", e);
                    }
                    fieldSupport.setInstance(currentObj);
                    Builder.of(initInstance).with(HashMap::put, currentClass, currentObj).build();
                });
                return initInstance;
            }).collect(HashMap::new, HashMap::putAll, HashMap::putAll);
        }).collect(HashMap::new, HashMap::putAll, HashMap::putAll);

        // 接口型参数注入 这里主要涉及Mybatis模拟
        // 保存初次实例化对象
        HashMap<Class<?>, Object> initInterfaceInstance = Builder.of(HashMap<Class<?>, Object>::new).build();
        HashMap<Class<?>, Object> copyInitInterfaceInstance = Optional.ofNullable(attributeInjection).orElseGet(
                AttributeInjection::new).getToBeInjected().values().stream().map(fieldSupports -> {
            return fieldSupports.stream().filter(fieldSupport -> fieldSupport.getFieldType().isInterface()).collect(Collectors.toList());
        }).map(fieldSupports -> {
            return fieldSupports.stream().map(fieldSupport -> {
                // 开启对私有变量进行注入
                fieldSupport.getField().setAccessible(true);
                ClassSupport classSupport = fieldSupport.getClassSupport();
                Class<?> currentClass = classSupport.getClazz();
                //TODO 针对属性带有 Autowired.class 注解处理
                fieldSupport.getAnnotations().stream().filter(annotation -> {
                    return annotation instanceof Autowired;
                }).forEach(annotation -> {// 这里没有拆解是为了方便理解
                    // 针对属性进行注入
                    Object currentObj = fieldSupport.getInstance();
                    try {
                        fieldSupport.getField().set(currentObj, Analysis.getMapperClassByType(fieldSupport.getFieldType(), configInfo, newInjectedObject));
                    } catch (IllegalAccessException e) {
                        log.error("", e);
                    }
                    fieldSupport.setInstance(currentObj);
                    Builder.of(initInterfaceInstance).with(HashMap::put, currentClass, currentObj).build();
                });
                //TODO 针对属性带有 Resource.class 注解处理
                fieldSupport.getAnnotations().stream().filter(annotation -> {
                    return annotation instanceof Resource;
                }).forEach(annotation -> {
                    // 针对属性进行注入
                    Object currentObj = fieldSupport.getInstance();
                    try {
                        fieldSupport.getField().set(currentObj, Analysis.getMapperClassByType(fieldSupport.getFieldType(), configInfo, newInjectedObject));
                    } catch (IllegalAccessException e) {
                        log.error("", e);
                    }
                    fieldSupport.setInstance(currentObj);
                    Builder.of(initInterfaceInstance).with(HashMap::put, currentClass, currentObj).build();
                });
                return initInterfaceInstance;
            }).collect(HashMap<Class<?>, Object>::new, HashMap::putAll, HashMap::putAll);
        }).collect(HashMap::new, HashMap::putAll, HashMap::putAll);
        initInstance.putAll(initInterfaceInstance);
        // 取出所有的RestController.class
        HashMap<Class<?>, Object> controllerClass = initInstance.entrySet().stream().filter(classObjectEntry -> !Objects.isNull(classObjectEntry.getKey().getAnnotation(RestController.class)))
                .collect(HashMap<Class<?>, Object>::new, (hashMap, entry) -> hashMap.put(entry.getKey(), entry.getValue()), HashMap::putAll);
        return Builder.of(attributeInjection)
                .with(AttributeInjection::addSingleton, AttributeInjection.class, initInstance)
                .with(AttributeInjection::addSingleton, RestController.class, controllerClass)
                .with(AttributeInjection::addSingleton, SqlInfo.class, newInjectedObject).build();
    }

    // 7. 初始化调度器  filter dispatch
    public static HashMap<String, MethodSupport> initDispatch(Map<String, ClassSupport> tobeInstance, AttributeInjection attributeInjection) {
        // 关联代理对象和路径
        HashMap<Class<?>, Object> controllerClass = (HashMap<Class<?>, Object>) attributeInjection.getSingleton().get(RestController.class);
        HashMap<Class<?>, ClassSupport> classToConfig = tobeInstance.values().stream().map(classSupport -> {
            return Builder.of(HashMap<Class<?>, ClassSupport>::new).with(HashMap::put, classSupport.getClazz(), classSupport).build();
        }).collect(HashMap<Class<?>, ClassSupport>::new, HashMap::putAll, HashMap::putAll);
        HashMap<String, MethodSupport> routeInfos = controllerClass.keySet().stream().map(clazz -> {
            ClassSupport classSupport = classToConfig.get(clazz);
            // 地址和方法
            HashMap<String, MethodSupport> routeInfo = classSupport.getRoutInfors().stream().map(RouteSupport::getRoute).collect(HashMap<String, MethodSupport>::new, HashMap::putAll, HashMap::putAll);
            routeInfo.values().forEach(methodSupport -> {
                // 把最终的代理对象插入进去
                methodSupport.setInstance(controllerClass.get(clazz));
            });
            return routeInfo;
        }).collect(HashMap<String, MethodSupport>::new, HashMap::putAll, HashMap::putAll);
        return routeInfos;
    }

    // 8. 初始化过滤器和  filter
    public static FilterChain initFilterAnd(ConfigInstance configObj) {
        return (FilterChain) configObj.getAnnotationInstance().get(Filter.class);
    }
}
